package main

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	"rongyy-oss/helpers"
	"text/template"

	"github.com/joho/godotenv"
)

type H = map[string]interface{}

func sendJson(w http.ResponseWriter, r *http.Request, data H) {
	bytes, _ := json.Marshal(data)

	w.Header().Add("Content-Type", "application/json;utf-8")
	w.Header().Add("Access-Control-Allow-Origin", r.Header.Get("Origin"))
	w.Header().Add("Access-Control-Allow-Headers", "Content-Type, Authorization, Accept, Referer, User-Agent")
	w.Header().Add("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE, PUT")
	w.Header().Add("Access-Control-Expose-Headers", "Content-Length, Access-Control-Allow-Origin, Access-Control-Allow-Headers, Content-Type")
	w.Header().Add("Access-Control-Allow-Credentials", "true")

	w.Write(bytes)
}

func main() {
	defer func() {
		if err := recover(); err != nil {
			fmt.Printf("%s\n", err)
		}
	}()

	err := godotenv.Load()
	if err != nil {
		log.Fatal(err)
		return
	}

	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		if r.Method == "OPTIONS" {
			sendJson(w, r, H{
				"success": true,
				"data":    nil,
			})
			return
		}
		if r.Method != "POST" {
			htmlByte, err := ioutil.ReadFile("./templates/readme.html")
			if err != nil {
				http.Error(w, err.Error(), http.StatusInternalServerError)
			}
			t, err := template.New("readme").Parse(string(htmlByte))
			if err != nil {
				fmt.Println("parse html文件失败,err", err)
				return
			}
			t.Execute(w, nil)
			return
		}

		formField := helpers.NewParamField(r)

		fieldName := formField.GetDefault("name", "file")
		bucketName := formField.GetDefault("bucket", "hzd-hub")
		ossBaseRoot := formField.GetDefault("dir", "default")

		r.ParseMultipartForm(32 << 20)
		r.Body = http.MaxBytesReader(w, r.Body, 32<<20+512) //32.5Mb
		files := r.MultipartForm.File[fieldName]
		if len(files) == 0 {
			sendJson(w, r, H{
				"success": false,
				"data":    nil,
				"error":   "未发现的文件上传，请检查",
			})
			return
		}

		fileObjectKeys := make([]string, 0)

		for _, file := range files {
			contentType := file.Header.Get("Content-Type")
			localFile, err := helpers.NewUploader().UploadFile(file)
			if err != nil {
				sendJson(w, r, H{
					"success": false,
					"data":    nil,
					"error":   err.Error(),
				})
				return
			}

			fileObjectKey, err := helpers.NewOss().Transmit(bucketName, ossBaseRoot, localFile, contentType)
			if err != nil {
				sendJson(w, r, H{
					"success": false,
					"data":    nil,
					"error":   err.Error(),
				})
				return
			}
			fileObjectKeys = append(fileObjectKeys, fileObjectKey)
		}

		baseUrl := fmt.Sprintf("https://%s.oss-cn-chengdu.aliyuncs.com", bucketName)

		sendJson(w, r, H{
			"success": true,
			"data": H{
				"baseUrl": baseUrl,
				"objs":    fileObjectKeys,
			},
			"error": "",
		})
	})

	fmt.Printf("Listening and serving HTTP on %s\n", "http://0.0.0.0:8082")
	http.ListenAndServe("0.0.0.0:8082", nil)
}
